<template>
  <div>
    <a-card>
      <p class="button_p">
        <a-button class="button_p_button" @click="saveDb">保存</a-button>
        <a-button class="button_p_button" @click="handlerRedo">恢复</a-button>
        <a-button class="button_p_button" @click="handlerUndo">撤销</a-button>
        <a-button class="button_p_button" @click="handlerZoom(0.1)">放大</a-button>
        <a-button class="button_p_button" @click="handlerZoom(-0.1)">缩小</a-button>
        <a-button class="button_p_button" @click="handlerZoom(1)">还原</a-button>
        <a-button class="button_p_button" @click="saveSvg">保存SVG</a-button>
        <a-button class="button_p_button" @click="saveXML">保存XML</a-button>
        <a-button class="button_p_button" @click="openFileInput">加载本地XML</a-button>
        <input type="file" id="files" style="display: none;margin-left: 10px" @change="loadXML"/>
      </p>
      <div class="containers">
        <div class="canvas" ref="canvas"></div>
        <div class="bpmn-js-properties-panel" id="js-properties-panel"></div>
      </div>
    </a-card>
  </div>
</template>

<script>
import BpmnModeler from 'bpmn-js/lib/Modeler'
import {XmlStr} from '@/mock/XmlStr'
import customTranslate from '../../utils/act-chinese/customTranslate'
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
import propertiesPanelModule from 'bpmn-js-properties-panel'
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
import activitiModdleDescriptor from '../../utils/act-chinese/activiti.json'
import {postAction, getAction} from '../../api/manage'

export default {
  name: 'Modeler',
  data() {
    return {
      bpmnModeler: null,
      container: null,
      canvas: null,
      scale: 1,
      xmlStr: '',
      processModel: {},
      toDbModel: {},
      url: {
        //保存流程定义数据
        saveProcessDefinitionData: '/act/model/saveProcessDefinitionData',
        getProcessDefinitionData: '/act/model/getProcessDefinitionData'
      }
    }
  },
  // mounted() {
  //   // 生命周期钩子，在组件加载完成后调用init函数进行创建初始化Bpmn-js建模器
  //   this.init()
  // },
  watch: {
    processModel: 'processModelChange'
  },
  methods: {
    //初始化
    init() {
      const canvas = this.$refs.canvas
      // 将汉化包装成一个模块
      const customTranslateModule = {
        translate: ['value', customTranslate]
      }
      this.bpmnModeler = new BpmnModeler({
        container: canvas,
        keyboard: {
          bindTo: window
        },
        propertiesPanel: {
          parent: '#js-properties-panel'
        },
        additionalModules: [
          // 汉化模块
          customTranslateModule,
          propertiesProviderModule,
          propertiesPanelModule
        ],
        moddleExtensions: {
          camunda: camundaModdleDescriptor
        }
      })
      this.createNewDiagram()
    },
    //创建新的模型
    createNewDiagram() {
      try {
        const result = this.bpmnModeler.importXML(this.xmlStr)
        const {warnings} = result
        console.log(warnings)
      } catch (err) {
        console.log(err.message, err.warnings)
      }
    },
    //恢复
    handlerRedo() {
      this.bpmnModeler.get('commandStack').redo()
    },
    //撤销
    handlerUndo() {
      this.bpmnModeler.get('commandStack').undo()
    },
    //操作界面比例
    handlerZoom(radio) {
      const newScale = !radio ? 1.0 : this.scale + radio
      this.bpmnModeler.get('canvas').zoom(newScale)
      this.scale = newScale
    },
    //保存为xml
    async saveXML() {
      try {
        const result = await this.bpmnModeler.saveXML({format: true})
        const {xml} = result
        const replaceXml = xml.replace(/camunda.org\/schema\/1.0\/bpmn/ig,"activiti.org/bpmn").replace(/camunda/ig,"activiti");
        var xmlBlob = new Blob([replaceXml], {
          type: 'application/bpmn20-xml;charset=UTF-8,'
        })
        var downloadLink = document.createElement('a')
        downloadLink.download = 'ops-coffee-bpmn.bpmn'
        downloadLink.innerHTML = 'Get BPMN SVG'
        downloadLink.href = window.URL.createObjectURL(xmlBlob)
        downloadLink.onclick = function (event) {
          document.body.removeChild(event.target)
        }
        downloadLink.style.visibility = 'hidden'
        document.body.appendChild(downloadLink)
        downloadLink.click()
      } catch (err) {
        console.log(err)
      }
    },
    //保存为svg
    async saveSvg() {
      try {
        const result = await this.bpmnModeler.saveSVG()
        const {svg} = result

        var svgBlob = new Blob([svg], {
          type: 'image/svg+xml'
        })

        var downloadLink = document.createElement('a')
        downloadLink.download = 'ops-coffee-bpmn.svg'
        downloadLink.innerHTML = 'Get BPMN SVG'
        downloadLink.href = window.URL.createObjectURL(svgBlob)
        downloadLink.onclick = function (event) {
          document.body.removeChild(event.target)
        }
        downloadLink.style.visibility = 'hidden'
        document.body.appendChild(downloadLink)
        downloadLink.click()
      } catch (err) {
        console.log(err)
      }
    },
    //加载本地xml文件
    loadXML() {
      const that = this
      //获取input框
      let input = document.getElementById(`files`)
      //获取上传的本地文件
      let file = input.files[0]

      var reader = new FileReader()
      reader.readAsText(file)
      reader.onload = function () {
        that.xmlStr = this.result.replace(/activiti.org\/bpmn/ig,"camunda.org/schema/1.0/bpmn").replace(/activiti/ig,"camunda");
        that.createNewDiagram()
      }
      //加载完成关闭input框
      input.style.display = 'none'
    },
    //打开input框
    openFileInput() {
      let files = document.getElementById('files')
      files.style.display = 'inline-block'
    },
    //保存模型定义数据到后台
    saveDb() {
      //获取bpmnStr  this.bpmnModeler.saveXML({format: true}, (err, data) => {
  //     let xml = data.replace(/camunda.org\/schema\/1.0\/bpmn/ig,"activiti.org/bpmn").replace(/camunda/ig,"activiti");
	// ……
  //   });
      this.bpmnModeler.saveXML({format: true}).then(res => {
        this.toDbModel.bpmnStr = res.xml.replace(/camunda.org\/schema\/1.0\/bpmn/ig,"activiti.org/bpmn").replace(/camunda/ig,"activiti");

      })
      //获取svgStr
      this.bpmnModeler.saveSVG().then(res => {
        this.toDbModel.svgStr = res.svg
      })
      this.toDbModel.modelId = this.processModel.id
      this.toDbModel.name = this.processModel.name
      this.toDbModel.key = this.processModel.key
      this.toDbModel.category = this.processModel.category
      //保存流程定义数据
      postAction(this.url.saveProcessDefinitionData, this.toDbModel).then(res => {
        if (res.success) {
          this.$message.success(res.message)
          this.$router.push({path: '/activiti/Manage'})
          // this.$router.push({ path: '/activiti/design' })
        } else {
          this.$message.error(res.message)
        }
      })
    },
    //加载模型定义数据
    loadXmlStr() {
      //调用后台接口，获取模型定义数据
      getAction(this.url.getProcessDefinitionData, {modelId: this.processModel.id}).then(res => {
        if (res.success) {
          if (res.result && res.result.modelEditorSource) {
            //如果从后台拿到模型定义数据，则直接使用后台数据
            //.replace(/camunda.org\/schema\/1.0\/bpmn/ig,"activiti.org/bpmn").replace(/camunda/ig,"activiti");
            this.xmlStr = res.result.modelEditorSource.replace(/activiti.org\/bpmn/ig,"camunda.org/schema/1.0/bpmn").replace(/activiti/ig,"camunda");
          }
        }
        //判断是否加载到后台模型定义数据。
        if (!this.xmlStr) {
          //没有加载到数据则生成默认模版
          if (null != this.processModel && null != this.processModel.id) {
            this.xmlStr = XmlStr(this.processModel)
          }
        }
        //界面初始化
        this.init()
      })
    },
    //监听processModel改变
    processModelChange(val, oldVal) {
      this.loadXmlStr()
    }
  }
}
</script>

<style lang="less" scoped>
.containers {
  background: #9e9e9e;
  overflow: auto;
  background-image: linear-gradient(90deg,
  rgba(220, 220, 220, 0.5) 6%,
  transparent 0),
  linear-gradient(rgba(192, 192, 192, 0.5) 6%, transparent 0);
  background-size: 12px 12px;
  width: 100%;
  height: calc(100vh);
  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}

.canvas {
  width: 100%;
  height: 100%;
}

.button_p {
  margin-bottom: 20px;

  .button_p_button {
    margin-left: 10px;
  }
}

.bpmn-js-properties-panel {
  position: absolute;
  top: 0;
  right: 0px;
  width: 300px;
  height: 100vh;
}
</style>